import DynamicIcon from '@/platform/components/dynamic-icon/DynamicIcon';
import NavMenuType from '@/platform/types/nav-menu-type';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
import { Input } from 'antd';
import lodash from 'lodash';
import React, {
    useContext,
    useEffect, useRef, useState 
} from 'react';
import { useHistory } from 'react-router';
import CustomEmpty from '@/platform/components/custom-empty/CustomEmpty';
import NavMenuContext from '@/platform/contexts/nav-menu-context';
import PropTypes from 'prop-types';
import classes from './NavMenu.module.less';
import NavMenuNode from './NavMenuNode';


const NavMenu:React.FC<NavMenuType> = (props) => {
    const dispatchNavMenuState = useContext(NavMenuContext);
    const history = useHistory();
    
    const [searchMsgHidden, setSearchMsgHidden] = useState(true);
    const [data, setData] = useState<Object[]>([]);
    const [allData, setAllData] = useState<Object[]>([]);

    const searchInputRef = useRef<any>();

    useEffect(() => {
        setData(props.treeData);
        setAllData(props.treeData);
    }, [props.treeData])

    const pushSearchMenu = (item: any, menuIdList: any) => {
        menuIdList.push(item[props.nodeConfig.menuId as string]);
        const itemChildren = item[props.nodeConfig.menuChildren as string];
        if (itemChildren && itemChildren.length > 0) {
            for (const subItem of itemChildren) {
                pushSearchMenu(subItem, menuIdList);
            }
        }
    };
  
    const checkSearchMenuIdExists = (id: string, menuIdList: any) => {
        for (const menuId of menuIdList) {
            if (menuId === id) {
                return true;
            }
        }
        return false;
    };

    const searchItem = (item: any, menuList: any, menuIdList: any, keyWord: any) => {
        item[props.nodeConfig.menuState as string] = false;
        //关键字匹配，并且不在列表中的
        if (
            item[props.nodeConfig.menuLabel as string].match(keyWord)
          && !checkSearchMenuIdExists(item[props.nodeConfig.menuId as string], menuIdList)
        ) {
            menuList.push(item);
            pushSearchMenu(item, menuIdList);
        }
  
        //存在子菜单的，递归子菜单
        const itemChildren = item[props.nodeConfig.menuChildren as string];
        if (itemChildren && itemChildren.length > 0) {
            for (const subItem of itemChildren) {
                searchItem(subItem, menuList, menuIdList, keyWord);
            }
        }
    };
  
    

    const onSearch = () => {
        const tempData: any = allData;
        const searchTxt = searchInputRef.current.input.value;
        setSearchMsgHidden(true);

        if ('' !== searchTxt) {
            const keyWord = new RegExp(searchTxt);
            const menuList:any[] = [];
            const menuIdList:any[] = [];

            for (const item of tempData) {
                searchItem(item, menuList, menuIdList, keyWord);
            }

            if (menuList.length > 0) {
                setData(menuList);
            } else {
                setSearchMsgHidden(false);
            }
        } else {
            setData(allData)
        }
    }

    const isLeaf = (item: any) => (
        !item[props.nodeConfig.menuChildren as string]
          || !item[props.nodeConfig.menuChildren as string].length
    );

    const itemClicked = (item: any) => () => {
        if (!isLeaf(item)) {
            item[props.nodeConfig.menuState as string] = !item[props.nodeConfig.menuState as string];
            setData(lodash.clone(data));
        } else {
            history.push(item[props.nodeConfig.menuUrl as string]);
            dispatchNavMenuState();
        }
    };

    const getObjProp = (obj: any, prop: string) => obj[props.nodeConfig[prop]];

    return (
        <div className={classes["app-nav-menu-container"]}>
            <div className={classes["app-nav-menu-search-container"]}>
                <Input.Search ref={searchInputRef} placeholder="搜索菜单..." onSearch={onSearch} />
            </div>
            <div className={classes["app-nav-menu-tree"]}>
                <OverlayScrollbarsComponent
                    options={{
                        scrollbars: {
                            autoHide: 'leave',
                            autoHideDelay: 100
                        }
                    }}
                    className={classes["app-nav-menu-tree-scroll"]}
                >
                    <div className={classes["app-nav-menu-tree-content"]}>
                        {
                            !searchMsgHidden && (
                                <div className={classes["app-search-msg"]}>
                                    <CustomEmpty description="搜索不到菜单！" />
                                </div>
                            )
                        }
                        {
                            searchMsgHidden && (
                            
                                <ul className={classes["app-nav-menu-ul"]}>
                                    {
                                        data.map((item:any) => (
                                            <li key={item.id}>
                                                <div className={classes["app-nav-menu-node-block"]} onClick={itemClicked(item)}>
                                                    <div className={classes["app-node"]}>
                                                        {
                                                            !isLeaf(item) && getObjProp(item, 'menuState') && <DynamicIcon iconName="DownOutlined" />
                                                        }
    
                                                        {
                                                            !isLeaf(item) && !getObjProp(item, 'menuState') && <DynamicIcon iconName="RightOutlined" />
                                                        }
                                                
                                                    </div>
                                                    <div>
                                                        <DynamicIcon
                                                            iconName={getObjProp(item, 'menuIcon')}
                                                            iconProps={{
                                                                className: classes['app-node-icon']
                                                            }}
                                                        />
                                                        <span>{ getObjProp(item, 'menuLabel') }</span>
                                                    </div>
    
                                                </div>
                                                <NavMenuNode nodeData={item} nodeConfig={props.nodeConfig} level={1} />
                                            </li>
                                        ))
                                    }
                                
                                </ul>
                            )
                        }
                    </div>
                </OverlayScrollbarsComponent>
            </div>
        </div>
    )
};

NavMenu.defaultProps = {
    nodeConfig: {
        menuId: 'id',
        menuParentId: 'parentId',
        menuLabel: 'text',
        menuIcon: 'icon',
        menuChildren: 'children',
        menuUrl: 'attr1',
        menuAttr: 'attributes',
        menuState: 'open'
    }
}

NavMenu.propTypes = {
    treeData: PropTypes.array.isRequired,
    nodeConfig: PropTypes.any
}

export default NavMenu;

